package com.easylinkin.linkappapi.common.utils.io;

import com.easylinkin.linkappapi.common.constant.CommonConstant;
import com.easylinkin.linkappapi.common.utils.file.GridFile;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;

/**
 *  输出流工具类
 * @author
 * @date
 */
public class OutputStreamUtil {

    protected static final Logger log = LoggerFactory.getLogger(OutputStreamUtil.class);

    private static String[] IEBrowserSignals = {"MSIE", "Trident", "Edge"};

    public static boolean isMSBrowser(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        for (String signal : IEBrowserSignals) {
            if (userAgent.contains(signal)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 文件下载解决乱码问题 2019-06-04 create by cqChen
     * 最新的360 QQ 谷歌测试均无文件名乱码，截止时间20190604。
     * @param request
     * @param response
     * @param fileName 文件名
     * @return
     * @throws IOException
     */
    public static OutputStream getOutputStream(HttpServletRequest request, HttpServletResponse response, String fileName) throws IOException {
        OutputStream outStream = response.getOutputStream();
        response.reset();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Type", "application/octet-stream");
        response.setHeader("Access-Control-Allow-Origin","*");
        boolean isMSIE = isMSBrowser(request);
        if (isMSIE) {
            //IE浏览器的乱码问题解决
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } else {
            //万能乱码问题解决
            fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
        }
        response.setHeader("Content-disposition", "attachment;filename=\"" + fileName + "\"");
        return outStream;
    }

    /**
     * 有乱码，360浏览器，QQ浏览器 2019-06-04 update
     * @param response
     * @param fileName
     * @return
     * @throws IOException
     */
    @Deprecated
    public static OutputStream getOutputStream(HttpServletResponse response, String fileName) throws IOException {
        OutputStream outStream = response.getOutputStream();
        response.reset();
        response.setCharacterEncoding("UTF-8");
        response.addHeader("Content-Type", "application/octet-stream");
        response.addHeader("Content-Disposition", "attachment; filename=\"" +
                new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\";filename*=UTF-8''"
                + new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
        return outStream;
    }

    /**
     * 解决文件下载跨域问题
     *
     */
    public static OutputStream getJsonpOutputStream(HttpServletResponse response, String fileName) throws IOException {
        OutputStream outStream = response.getOutputStream();
        response.reset();
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Content-Type", "application/octet-stream");
        response.setCharacterEncoding("UTF-8");
        response.addHeader("Content-Disposition", "attachment; filename=\"" +
                new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\";filename*=UTF-8''"
                + new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
        return outStream;
    }



    /**
     * 下载样表
     *
     * @param model 下载的展示文件名
     * @return 响应
     */
    public static ResponseEntity<byte[]> download(String model, String fileName) throws IOException {
        String path;
        ResponseEntity<byte[]> response = null;
        try {
//            path = ResourceUtils.getURL("classpath:").getPath();
//            File file = new File(path, "templates/quantity/" + model);
            File file = ResourceUtils.getFile("classpath:templates" + File.separatorChar +
                    "quantity" + File.separatorChar  + model);
            HttpHeaders headers = new HttpHeaders();
            //为了解决中文名称乱码问题
            String name = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            headers.setContentDispositionFormData("attachment", name);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            response = new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
        } catch (FileNotFoundException e) {
            log.error("找不到指定的文件", e);
        }
        return response;
    }

    /**
     * 获取文件名称，将文件名称编码，避免前端下载文件名称乱码。
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @param gridFile 文件对象
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String getGridFileName(HttpServletRequest request, HttpServletResponse response, GridFile gridFile) throws UnsupportedEncodingException {
        if(null == gridFile) {
            return "";
        }
        String fileName = gridFile.getFileName();
        if(StringUtils.isNotEmpty(fileName)) {
            response.setCharacterEncoding("UTF-8");
            boolean isMSIE = OutputStreamUtil.isMSBrowser(request);
            if (isMSIE) {
                //IE浏览器的乱码问题解决
                fileName = URLEncoder.encode(fileName, CommonConstant.CharsetName.UTF_8);
            } else {
                //万能乱码问题解决
                fileName = new String(fileName.getBytes(CommonConstant.CharsetName.UTF_8), CommonConstant.CharsetName.ISO_8859_1);
            }
        }
        return fileName;
    }

}
